package com.youbo.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.*;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;


/**
 * @author macy
 *
 */
public class HttpUtils {
    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * POST请求远程http页面
     *
     * @param contentUrl
     * @param json
     * @return
     */
    public static String post(String contentUrl, String json) {
        StringBuilder contentBuilder = new StringBuilder();
        HttpURLConnection connection = null;
        DataOutputStream out = null;
        BufferedReader reader = null;
        try {
            connection = (HttpURLConnection) new URL(contentUrl).openConnection();
            // 设置Socket超时
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(20000);
            // Post 请求不能使用缓存
            connection.setUseCaches(false);
            // URLConnection.setInstanceFollowRedirects是成员函数，仅作用于当前函数
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);// 是否输入参数
            // 要注意的是connection.getOutputStream会隐含的进行connect
            connection.connect();

            out = new DataOutputStream(connection.getOutputStream());
            // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面
            out.write(json.getBytes("utf-8"));
            out.flush();

            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));

            int buffer = 0;
            while ((buffer = reader.read()) != -1) {
                contentBuilder.append((char) buffer);
            }

        } catch (Exception e) {
            logger.error("网络访问错误:"+e.getMessage());
            // 异常处理
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }

            if (connection != null) {
                connection.disconnect();
            }
        }
        return contentBuilder.toString();
    }


    /**
     * POST请求远程https页面
     *
     * @param contentUrl
     * @param json
     * @return
     */
    public static String postHttps(String contentUrl,String json) {
        StringBuilder contentBuilder = new StringBuilder();
        HttpsURLConnection connection = null;
        DataOutputStream out = null;
        BufferedReader reader = null;
        try {
            HostnameVerifier hnv = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                }
            };

            X509TrustManager[] xtmArray = new X509TrustManager[] { trustManager };
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, xtmArray, new java.security.SecureRandom());

            if (sslContext != null) {
                HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            }
            HttpsURLConnection.setDefaultHostnameVerifier(hnv);

            connection = (HttpsURLConnection) new URL(contentUrl).openConnection();
            // 设置Socket超时
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(20000);
            // Post 请求不能使用缓存
            connection.setUseCaches(false);
            // URLConnection.setInstanceFollowRedirects是成员函数，仅作用于当前函数
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);// 是否输入参数
            connection.connect();

            out = new DataOutputStream(connection.getOutputStream());

            // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面
            out.writeBytes(json);
            out.flush();

            reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));

            int buffer = 0;
            while ((buffer = reader.read()) != -1) {
                contentBuilder.append((char) buffer);
            }
        } catch (Exception e) {
            // 异常处理
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return contentBuilder.toString();
    }




    /*******************************************************************/

    /**
     * 发送GET请求
     *
     * @param url
     *            目的地址
     * @param parameters
     *            请求参数，Map类型。
     * @return 远程响应结果
     */
    public static String sendGet(String url, Map<String, String> parameters) {
        String result="";
        BufferedReader in = null;// 读取响应输入流
        StringBuffer sb = new StringBuffer();// 存储参数
        String params = "";// 编码之后的参数
        try {
            // 编码请求参数
            if(null!=parameters){
                if(parameters.size()==1){
                    for(String name:parameters.keySet()){
                        sb.append(name).append("=").append(
                                java.net.URLEncoder.encode(parameters.get(name),
                                        "UTF-8"));
                    }
                    params="?"+sb.toString();
                }else{
                    for (String name : parameters.keySet()) {
                        sb.append(name).append("=").append(
                                java.net.URLEncoder.encode(parameters.get(name),
                                        "UTF-8")).append("&");
                    }
                    String temp_params = sb.toString();
                    params = "?"+temp_params.substring(0, temp_params.length() - 1);
                }
            }


            String full_url = url + params;
            System.out.println(full_url);
            // 创建URL对象
            java.net.URL connURL = new java.net.URL(full_url);
            // 打开URL连接
            java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL
                    .openConnection();
            // 设置通用属性
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            // 建立实际的连接
            httpConn.connect();
            // 响应头部获取
            Map<String, List<String>> headers = httpConn.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : headers.keySet()) {
                System.out.println(key + "\t：\t" + headers.get(key));
            }
            // 定义BufferedReader输入流来读取URL的响应,并设置编码方式
            in = new BufferedReader(new InputStreamReader(httpConn
                    .getInputStream(), "UTF-8"));
            String line;
            // 读取返回的内容
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result ;
    }

    /**
     * 发送POST请求
     *
     * @param url
     *            目的地址
     * @param parameters
     *            请求参数，Map类型。
     * @return 远程响应结果
     */
    public static String sendPost(String url, Map<String, String> parameters) {
        String result = "";// 返回的结果
        BufferedReader in = null;// 读取响应输入流
        PrintWriter out = null;
        StringBuffer sb = new StringBuffer();// 处理请求参数
        String params = "";// 编码之后的参数
        try {
            // 编码请求参数
            if(null!=parameters){
                if (parameters.size() == 1) {
                    for (String name : parameters.keySet()) {
                        sb.append(name).append("=").append(
                                java.net.URLEncoder.encode(parameters.get(name),
                                        "UTF-8"));
                    }
                    params = sb.toString();
                } else {
                    for (String name : parameters.keySet()) {
                        sb.append(name).append("=").append(
                                java.net.URLEncoder.encode(parameters.get(name),
                                        "UTF-8")).append("&");
                    }
                    String temp_params = sb.toString();
                    params = temp_params.substring(0, temp_params.length() - 1);
                }
            }
            // 创建URL对象
            java.net.URL connURL = new java.net.URL(url);
            // 打开URL连接
            java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL
                    .openConnection();
            // 设置通用属性
            httpConn.setRequestProperty("Accept", "*/*");
            httpConn.setRequestProperty("Connection", "Keep-Alive");
            httpConn.setRequestProperty("User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            // 设置POST方式
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            // 获取HttpURLConnection对象对应的输出流
            out = new PrintWriter(httpConn.getOutputStream());
            // 发送请求参数
            out.write(params);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应，设置编码方式
            in = new BufferedReader(new InputStreamReader(httpConn
                    .getInputStream(), "UTF-8"));
            String line;
            // 读取返回的内容
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String sendPostBody(String strURL,String body) {
        OutputStreamWriter out = null;
        BufferedReader in = null;// 读取响应输入流
        String result=null;
        try{
            URL url = new URL(strURL);// 创建连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST"); // 设置请求方式
            connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
            connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
            connection.connect();
            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
            out.append(body);
            out.flush();
            out.close();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line="";
            // 读取返回的内容
            while ((line = in.readLine()) != null) {
                result += line;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(null!=in){
                    in.close();
                }
                if(null!=out){
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }


    /**
     * 发送验证码
     * @param to 短信接收端手机号码集合，用英文逗号分开，每批发送的手机号数量不得超过200个
     * @param code 验证码内容
     * @return 成功={"statusCode":"000000","templateSMS":{"smsMessageSid":"2bd889e52ed24f0c80b487223bb93dc5","dateCreated":"20181203151014"}}
     */
    public static String sendPostSms(String to,String code) {
        String url="https://app.cloopen.com:8883";
        String result = "";// 返回的结果
        BufferedReader in = null;// 读取响应输入流
        PrintWriter out = null;
        String accountSid="8a216da8552a3cd401552d9c68d80297";
        String tiem=DateUtils.format(new Date(),"yyyyMMddHHmmss");
        String token="70781d4328d24ce197088ead9a3126cd";
        String templateId="394293";
        String sig=Tools.md5(accountSid+token+tiem).toUpperCase();
        Map<String,Object> parameters=new HashMap<>();

        try {
            url+="/2013-12-26/Accounts/"+accountSid+"/SMS/TemplateSMS?sig="+sig;
            String Authorization= Base64.getUrlEncoder().encodeToString((accountSid+":"+tiem).getBytes("utf-8"));
            parameters.put("to",to);
            parameters.put("appId","8a216da858ce0b3c0158ce27a9860057");
            parameters.put("templateId",templateId);
            //parameters.put("datas","");
            String[] datas=new String[1];
            datas[0]=code;
            parameters.put("datas",datas);
            // 创建URL对象
            java.net.URL connURL = new java.net.URL(url);
            // 打开URL连接
            java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL
                    .openConnection();

            httpConn.setRequestProperty("Accept", "application/json");
            httpConn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            httpConn.setRequestProperty("Authorization",Authorization);
            //httpConn.setRequestProperty("Content-Length", "Content-Length");
            String json=JsonTools.obj2String(parameters);

            // 设置POST方式
            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            // 获取HttpURLConnection对象对应的输出流
            out = new PrintWriter(httpConn.getOutputStream());
            // 发送请求参数
            out.write(json);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应，设置编码方式
            in = new BufferedReader(new InputStreamReader(httpConn
                    .getInputStream(), "UTF-8"));
            String line;
            // 读取返回的内容
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 主函数，测试请求
     *
     * @param args
     */
    public static void main(String[] args) {

        String result =sendPostSms("18653765897","8888");
        System.out.println(result);
    }

}